#include <stdio.h>
#include <stdlib.h>
#include "double_list.h"

_DNode *create_node(void)
{
    _DNode *new_node = NULL;

    new_node = (_DNode *)malloc(sizeof(_DNode));
    if (new_node == NULL)
    {
	printf("Malloc error in create new node\n");
	return NULL;
    }
    
    new_node->prev = NULL;
    new_node->next = NULL;
    new_node->elem = -1;

    return new_node;

}

void destroy_node(_DNode *node)
{
    if (node == NULL)
    {
	printf("In valid parameters\n");
	return;
    }

    free(node);
    return;
}

_DList create_list(void)
{
    _DList new_list = NULL;
    new_list = create_node();
    if (NULL == new_list)
    {
	printf("Malloc error in create new list\n");
	return NULL;
    }

    return new_list;
}

void destroy_list(_DList head)
{
    if (NULL == head)
    {
	return;
    }

    _DNode *tmp = NULL;
    
    for (tmp = head->next; NULL != tmp; tmp = head->next)
    {
	head->next = tmp->next;
	destroy_node(tmp);
    }

    free(head);

    return;
}

int insert_to_head(_DList head, _DNode *node)
{
    if (NULL == head || NULL == node)
    {
	printf("Invalid parameters!\n");
	return -1;
    }

    if (NULL == head->next)
    {
	head->next = node;
	node->prev = head;
	return 0;
    }

    node->next = head->next;
    head->next->prev = node;
    head->next = node;
    node->prev = head;

    return 0;
}

int insert_to_tail(_DList head, _DNode *node)
{
    if (NULL == head || NULL == node)
    {
	printf("Invalid parameters\n");
	return -1; 
    }

    _DNode *tmp = NULL;

    for (tmp = head; tmp->next != NULL; tmp = tmp->next);
    tmp->next = node;
    node->prev = tmp;

    return 0;
    

}

int delete_node(_DList head, _DNode *node)
{
    if (NULL == head || NULL == node)
    {
	printf("Invalid parameters\n");
	return -1;
    }

    _DNode *tmp = NULL;

    for (tmp = head->next; tmp != NULL; tmp = tmp->next)	/*here tmp may has been freed, so it is a mistake.*/
    {
	if (tmp->elem == node->elem)
	{
	    if (tmp->next == NULL)
	    {
		tmp->prev->next = NULL;
	    }
	    else
	    {
		tmp->prev->next = tmp->next;
		tmp->next->prev = tmp->prev;
	    }

	    free(tmp);
	}
    }
}
